package io.itit.ecp.admin.provide.action.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.common.enums.IActivityCarbonEmissionDataTypeEnums;
import io.itit.ecp.admin.provide.action.req.ActivityCarbonEmissionQueryReq;
import io.itit.ecp.admin.provide.action.resp.ActivityCarbonEmissionDetailResp;
import io.itit.ecp.admin.provide.action.resp.ActivityCarbonEmissionResp;
import io.itit.ecp.admin.provide.action.resp.CarbonSinkDataResp;
import io.itit.ecp.admin.provide.helper.SceneHelper;
import io.itit.ecp.admin.server.entity.*;
import io.itit.ecp.admin.server.service.IActivityCarbonEmissionDataService;
import io.itit.ecp.admin.server.service.IActivityCarbonEmissionService;
import io.itit.ecp.admin.server.service.IMeterDeviceService;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.IAdd;
import io.itit.grass.common.provide.action.validation.IQueryPage;
import io.itit.grass.common.provide.action.validation.IRequired;
import io.itit.grass.common.provide.action.validation.IUpdate;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Api(tags = "活动碳排放管理")
@RestController
@RequestMapping("/ecp-admin/activityCarbonEmission")
public class ActivityCarbonEmissionController {

    @Resource
    private IActivityCarbonEmissionService activityCarbonEmissionService;

    @Resource
    private IActivityCarbonEmissionDataService activityCarbonEmissionDataService;

    @Resource
    private IMeterDeviceService meterDeviceService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:search")
    public ResultResp<IPage<ActivityCarbonEmissionResp>> queryPage(@RequestBody @Validated(IQueryPage.class) ActivityCarbonEmissionQueryReq req) {
        Page<ActivityCarbonEmissionEntity> page = activityCarbonEmissionService.page(PageUtils.getPage(req, ActivityCarbonEmissionEntity.class), buildQW(req));
        return ResultResp.success(ConvertUtils.convert(page, ActivityCarbonEmissionResp.class));
    }

    @ApiOperation("详情")
    @PostMapping("detail")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:search")
    public ResultResp<ActivityCarbonEmissionResp> detail(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        ActivityCarbonEmissionResp carbonEmissionResp = ConvertUtils.copy(activityCarbonEmissionService.getById(req.getId()), ActivityCarbonEmissionResp.class);
        if (Objects.nonNull(carbonEmissionResp))
            carbonEmissionResp.setRelationData(activityCarbonEmissionDataService.selectByActivityCarbonId(carbonEmissionResp.getId()));
        return ResultResp.success(carbonEmissionResp);
    }

    @ApiOperation("详情")
    @PostMapping("detail2")
    public ResultResp<ActivityCarbonEmissionDetailResp> detail2(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        List<ActivityCarbonEmissionDataEntity> activityCarbonEmissionDataEntities = activityCarbonEmissionDataService.selectByActivityCarbonId(req.getId());
        Set<String> deviceIds = activityCarbonEmissionDataEntities.stream().filter(item -> StringUtils.pathEquals(item.getDataType(),
                        IActivityCarbonEmissionDataTypeEnums.RELATED_MEASURING_EQUIPMENT.getValue()))
                .map(ActivityCarbonEmissionDataEntity::getTargetId)
                .collect(Collectors.toSet());
        ActivityCarbonEmissionDetailResp resp = new ActivityCarbonEmissionDetailResp();
        if (!deviceIds.isEmpty()) {
            List<ActivityCarbonEmissionDetailResp.MeterDeviceDetailResp> list = Joins.of(MeterDeviceEntity.class)
                    .leftJoin(SceneProjectEntity.class, SceneProjectEntity::getId, MeterDeviceEntity::getSceneProjectId)
                    .select(SceneProjectEntity::getProjectName)
                    .end()
                    .leftJoin(EnergyConsumptionTypeEntity.class, EnergyConsumptionTypeEntity::getId, MeterDeviceEntity::getEnergyTypeId)
                    .selectAs(EnergyConsumptionTypeEntity::getEnergyName, ActivityCarbonEmissionDetailResp.MeterDeviceDetailResp::getEnergyTypeName)
                    .end()
                    .in(MeterDeviceEntity::getId, deviceIds).joinList(ActivityCarbonEmissionDetailResp.MeterDeviceDetailResp.class);
            resp.setMeterDeviceDetails(SceneHelper.i().setSceneInfo(list));
        }
        Set<String> greeningIds = activityCarbonEmissionDataEntities.stream().filter(item -> StringUtils.pathEquals(item.getDataType(),
                        IActivityCarbonEmissionDataTypeEnums.RELATED_GREENING.getValue()))
                .map(ActivityCarbonEmissionDataEntity::getTargetId)
                .collect(Collectors.toSet());
        if (!greeningIds.isEmpty()) {
            List<ActivityCarbonEmissionDetailResp.SinkDataDetailResp> sinkDataDetailResps = Joins.of(CarbonSinkEntity.class)
                    .selectAll()
                    .leftJoin(SceneProjectEntity.class, SceneProjectEntity::getId, CarbonSinkDataEntity::getSceneProjectId)
                    .select(SceneProjectEntity::getProjectName)
                    .end()
                    .leftJoin(CarbonSinkFactorEntity.class, CarbonSinkFactorEntity::getId, CarbonSinkDataEntity::getCarbonSinkId)
                    .selectAs(CarbonSinkFactorEntity::getType, CarbonSinkDataResp::getCarbonSinkName)
                    .end()
                    .in(CarbonSinkEntity::getId, greeningIds)
                    .joinList(ActivityCarbonEmissionDetailResp.SinkDataDetailResp.class);
            resp.setSinkDetails(SceneHelper.i().setSceneInfo(sinkDataDetailResps));
        }
        return ResultResp.success(resp);
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:add")
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) ActivityCarbonEmissionQueryReq req) {
        ActivityCarbonEmissionEntity activityCarbonEmissionEntity = ConvertUtils.copy(req, ActivityCarbonEmissionEntity.class);
        List<ActivityCarbonEmissionDataEntity> dataEntities = StringUtils.hasLength(req.getRelationDataJson()) ? JSON.parseArray(req.getRelationDataJson(), ActivityCarbonEmissionDataEntity.class) :
                Collections.emptyList();
        boolean result = activityCarbonEmissionService.saveOrUpdateActivityCarbonEmission(activityCarbonEmissionEntity, dataEntities);
        return ResultResp.success(result);
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) ActivityCarbonEmissionQueryReq req) {
        return this.add(req);
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:deleteById")
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        return ResultResp.success(activityCarbonEmissionService.removeById(req.getId()));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:activityCarbonEmission:batchDelete")
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        return ResultResp.success(activityCarbonEmissionService.removeBatchByIds(req.getIds(), 1000));
    }

    private Wrapper<ActivityCarbonEmissionEntity> buildQW(ActivityCarbonEmissionQueryReq req) {
        return Wrappers.<ActivityCarbonEmissionEntity>lambdaQuery()
                .like(StringUtils.hasLength(req.getActivityName()), ActivityCarbonEmissionEntity::getActivityName, req.getActivityName())
                .orderByDesc(ActivityCarbonEmissionEntity::getCreateTm);
    }
}
